<?php


namespace User\Service;
use Zend\Authentication\AuthenticationServiceInterface as AuthenticationService;
use Zend\Form\FormInterface as Form;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;

use Base\EventManager\EventProvider;
use User\Mapper\HydratorInterface as Hydrator;
use User\Options\UserServiceOptionsInterface as ServiceOptions;
use User\Mapper\UserInterface as UserMapper;
//use User\Options\UserServiceOptionsInterface as ServiceOptions;

class User extends EventProvider implements ServiceManagerAwareInterface
{

    /**
     * @var UserMapper
     */
    protected $userMapper;

    /**
     * @var AuthenticationService
     */
    protected $authService;

    /**
     * @var Form
     */
    protected $loginForm;

    /**
     * @var Form
     */
    protected $registerForm;

    /**
     * @var Form
     */
    protected $changePasswordForm;

    /**
     * @var ServiceManager
     */
    protected $serviceManager;

    /**
     * @var ServiceOptions
     */
    protected $options;

    /**
     * @var Hydrator
     */
    protected $formHydrator;

    /**
     * createFromForm
     *
     * @param array $data
     * @return \User\Entity\UserInterface
     * @throws Exception\InvalidArgumentException
     */
    public function register(array $data)
    {
        $entityClass = $this->getOptions()->getUserEntityClass();
        $form = $this->getRegisterForm();
        $form->setHydrator($this->getFormHydrator());
        $form->bind(new $entityClass);
        $form->setData($data);
        if($form->isValid())
        {
            $user = $form->getData();
            $events= $this->getEventManager();
            $user->setPassword($this->getFormHydrator()->getCryptoService()->create($user->getPassword()));
            $user->setCreatedOn(strtotime('now'));
            
            $events->trigger(__FUNCTION__, $this, compact('user', 'form'));
            $this->getUserMapper()->insert($user);
            $events->trigger(__FUNCTION__.'.post', $this, compact('user', 'form'));
            return $user;
        }
        return false;
    }


    /*
     * get userMapper
     * return userMapper
     */
    public function getUserMapper()
    {
        if(!$this->userMapper)
        {
            //$userMapper = $this->serviceManager->get('user_mapper');
            $this->setUserMapper($this->serviceManager->get('user_mapper'));
        }
        return $this->userMapper;
    }

    /*
     * set userMapper
     *
     */
    public function setUserMapper(UserMapper $userMapper)
    {
        $this->userMapper = $userMapper;
        return $this;
    }

    /**
     * getAuthService
     *
     * @return AuthenticationService
     */
    public function getAuthService()
    {
        if (null === $this->authService) {
            $this->setAuthService($this->serviceManager->get('user_auth_service'));
        }
        return $this->authService;
    }

    /**
     * setAuthenticationService
     *
     * @param AuthenticationService $authService
     * @return User
     */
    public function setAuthService(AuthenticationService $authService)
    {
        $this->authService = $authService;
        return $this;
    }


    /**
     * @return Form
     */
    public function getRegisterForm()
    {
        if (null === $this->registerForm) {
            $this->setRegisterForm($this->serviceManager->get('user_register_form'));
        }
        return $this->registerForm;
    }

    /**
     * @param Form $registerForm
     * @return User
     */
    public function setRegisterForm(Form $registerForm)
    {
        $this->registerForm = $registerForm;
        return $this;
    }


    /**
     * get service options
     *
     * @return UserServiceOptionsInterface
     */
    public function getOptions()
    {
        if (!$this->options instanceof ServiceOptions) {
            $this->setOptions($this->serviceManager->get('user_module_options'));
        }
        return $this->options;
    }

    /**
     * set service options
     *
     * @param ServiceOptions $options
     */
    public function setOptions(ServiceOptions $options)
    {
        $this->options = $options;
    }


    /*
     * return form Hydrator
     */
    public function getFormHydrator()
    {
        if(!$this->formHydrator instanceof Hydrator)
        {
            $this->setFormHydrator($this->serviceManager->get('user_hydrator'));
        }
        return $this->formHydrator;
    }

    public function setFormHydrator(Hydrator $formHydrator)
    {
        $this->formHydrator = $formHydrator;
        return $this;
    }
    
    /**
     * Retrieve service manager instance
     *
     * @return ServiceManager
     */
    public function getServiceManager()
    {
        return $this->serviceManager;
    }

    /**
     * Set service manager instance
     *
     * @param ServiceManager $serviceManager
     * @return User
     */
    public function setServiceManager(ServiceManager $serviceManager)
    {
        $this->serviceManager = $serviceManager;
        return $this;
    }

} 